    //Direction codes constants
    var D_LEFT = 1 ;  /* Left direction  */
    var D_RIGHT = 2 ; /* Right direction */
    var D_UP = 3 ;    /* Up direction    */
    var D_DOWN = 4 ;  /* Down direction  */
    //--------------------------------------------------------------------------------
    //Objects codes constants
    var EMPTY = 0 ;           /* Empty case */ 
    var WALL = 1 ;            /* Wall code */
    var SPECIAL_WALL = 21 ;   /* SpecialWall code */
    var MY_MIAOU = 2 ;        /* Yellow cat code */
    var BLACK_CAT = 3 ;       /* Black cat code */
    var RED_FISH = 4 ;        /* Red fish code */
    var YELLOW_FISH = 5 ;     /* Yellow fish code */
    var BLUE_FISH = 6 ;       /* Blue fish code */
    var BLACK_WHITE_CAT = 7 ; /* Black cat code */
    var SHOE = 8 ;            /* Shoe code */
    var HOME = 20 ;           /* Home code */
    //--------------------------------------------------------------------------------
    //Image filename objects constants
    //NB : image filename must exists in the ./images directory and must be
    //     in PNG format
    var IMG_WALL = 'wall' ; 
    var IMG_MY_MIAOU = 'my_miaou' ; 
    var IMG_BLACK_CAT = 'black_cat';
    var IMG_BLACK_WHITE_CAT = 'black_white_cat';
    var IMG_BLUE_FISH = 'blue_fish';
    var IMG_RED_FISH = 'red_fish';
    var IMG_YELLOW_FISH = 'yellow_fish';
    var IMG_HOME = 'home' ;
    var IMG_SHOE = 'shoe' ;
    //--------------------------------------------------------------------------------
    //Speed constants
    var SPEED_SLOW   = 1500 ; 
    var SPEED_MIDDLE = 500 ; 
    var SPEED_HIGH   = 300 ; 
    var currentSpeed ; 
    var timer; 
   
    //--------------------------------------------------------------------------------
    //Other constants
    var DEBUG_MODE=1 ; 
    
    var gameTable = new Array();
    var ORI_TOP_PX=0;
    var ORI_LFT_PX=0;
    var topPx=0;
    var lftPx=0;

    var H ; /* Height value */
    var W ; /* Width value */
    var miaou  ; /* The miaou's object */
    var blackMiaou ; /* The black miaou's object */
    var blackWhiteMiaou ; /* The black & white miaou's object */
    var autoMoveTimeOut = 2000 ; /* Time out when automatic move for every move */
    var badMiaou=new Array();
    var autoMoveDone;
    var nbTotalFish=0 ; /* The number of fish placed in the game */
    var nbEatFish=0 ; /* The number of eaten fish */
    var nbBadMiaou ; 
    var isHomeAvailable ; /* Flag to enter home */
    var currentLevel = 0 ; /* Current level */ 
    var iScoreValue=0;
    var autoMoveMiaou;
    
    var badMiaou;
    
/**
 * Game initialization
 */    
function init() {

    //Remove all body's tags
    if ( document.body == null ) {
       var mySpan = document.createElement("span");
        mySpan.innerHTML = "Go";
        mySpan.style.color = "red";
        document.body.appendChild(mySpan);
    }   
    else if (document.body.childNodes.length>1) {
        while(document.body.hasChildNodes()) document.body.removeChild(document.body.firstChild);
    }
    
    topPx=0;
    lftPx=0;
    SPEED = SPEED_SLOW ; /* Speed value in milliseconds */

    ht="";
    H=25 ; /* Height value */
    W=25 ; /* Width value */
    autoMoveTimeOut = 2000
    badMiaou=new Array();
    nbBadMiaou=0;
    blackMiaou=null;
    blackWhiteMiaou=null;
    gameTable = new Array();
    gameTable = levels[currentLevel] ; 
    nbTotalFish=0 ; /* The number of fish placed in the game */
    nbEatFish=0 ; /* The number of eaten fish */
    isHomeAvailable=false ;
}

/**
 * Go to the next level 
 */
function nextLevel() {
    
    /* Clear variables */
    badMiaou=null;
    blackMiaou=null;
    blackWhiteMiaou=null;
    gameTable =null;
    clearInterval(timer);
    alert("Vous avez gagné !!");
    currentLevel++; /* Increase current level */
    /* start */
    start();
}

/**
 * Adapt the game with the screen size
 */
function adaptScreen() {
    
    var maxLength=0;
    var currLength=0;
    
    var currTable = new Array();
    currTable = levels[currentLevel] ; 
    for(i=0;i<currTable.length;i++) {
        currLength=0;
        var currRow=currTable[i];	
        for(j=0;j<currRow.length;j++) { 
            if ( currRow[j]!=null )  currLength++;
        }
        //Next row, store maximum length if needed
        if ( currLength>maxLength) maxLength=currLength;
    }
    
    maxLength++; //Add a bonus case
    //Calculate new case's width
    W=Math.round( screen.width / maxLength ) ;
    H=W;
    
    //Define the left game origin (in pixels)
    ORI_LFT_PX=Math.round(W/2); 
    
}


/**
 * Display the home image and enable the exit
 */
function displayHome() {
    
    document.getElementById('homeId').innerHTML=addImg(IMG_HOME); 
    isHomeAvailable=true;
}

/** 
 * Display the score
 * 
 * The score's numbers are graphically converted
 * 
 * @param int The score value
 */
function displayScore( iScoreValue ) {
   var scId=document.getElementById('scoreId');
   var sScoreValue=""+iScoreValue;
   if ( iScoreValue<10 ) {
      //Format 01, 02 ...
      scId.innerHTML= addImg(IMG_BLUE_FISH)+addImg("0")+addImg(iScoreValue);
   }
   else {
      scId.innerHTML=addImg(IMG_BLUE_FISH)+addImg(sScoreValue.substring(0,1))+addImg(sScoreValue.substring(1)); 
   }
}

/**
 * Add an html image tag. 
 * 
 * The image's height is defined with the H constant,
 * the image's width is defined with the W constant.
 * 
 * The image must be in PNG format and placed in the ./images directory.
 * 
 * @param string The image's name
 * @retur string The html statement ie <IMG SRC ... />
 */ 
function addImg( sImgName ) {
    
    return "<IMG SRC='./images/"+sImgName+".png' height='"+H+"' width='"+W+"'/>";
}

/**
 * Add an html div tag to the body document. 
 * 
 * The div has the following style attributes :
 *  - position = absolute
 *  - top = iTopPx parameter (in pixels)
 *  - left = iLftPx parameter (in pixels)
 *  
 *  @param string The div identifier.
 *  @param int The distance from 0 top origin.
 *  @param int The distance from 0 left origin.
 *  @param string Optional content to include between the <DIV> and </DIV> tags.
 */
function addDiv( sDivId, iTopPx, iLftPx, sContent) {
    
    var newDiv = document.createElement("div");
    newDiv.id=sDivId;
    newDiv.style.position="absolute";
    newDiv.style.top= iTopPx+"px" ; 
    newDiv.style.left=iLftPx+"px";
    newDiv.innerHTML=sContent;
    document.body.appendChild(newDiv);
}

/**
 * Display the game table 
 */
function displayGameTable() {

badMiaou=new Array();
nbTotalFish=0;
lftPx=ORI_LFT_PX ;
for(i=0;i<gameTable.length;i++) {
  
    /* Get a row */
    var row=gameTable[i];		
    
    for(j=0;j<row.length;j++) {
	
        var sCode=""+row[j];
	/* Display game's images */
	if ( row[j]== WALL ) {
            /* Display the trash */
            addDiv("trash_"+i+"_"+j,topPx,lftPx,addImg(IMG_WALL));
  	}
  	if ( row[j]== MY_MIAOU ) {
            /* Display My Miaou hero */
            addDiv("miaouId", topPx,lftPx,addImg(IMG_MY_MIAOU));
            gameTable[i][j]=0;
            miaou=new miaouObject( MY_MIAOU , 'miaouId' , topPx, lftPx, j , i , W, H) ;
        }
  	if ( row[j]== BLACK_CAT ) {
            /* Display Black Miaou */
            addDiv("badMiaou_"+nbBadMiaou, topPx,lftPx,addImg(IMG_BLACK_CAT));
            /* Create a new miaou object */
            badMiaou[nbBadMiaou]=new miaouObject( BLACK_CAT , 'badMiaou_'+nbBadMiaou , topPx, lftPx, j , i, W,H) ;
            gameTable[i][j]=0;
            nbBadMiaou++;
        }
        if ( row[j]== RED_FISH ) {
            nbTotalFish++;
            /* Display the red fish */
            addDiv("fish_"+i+"_"+j, topPx,lftPx,addImg(IMG_RED_FISH));
            
        }
	if ( row[j]== YELLOW_FISH ) {
            nbTotalFish++;
            /* Display the yellow fish */
            addDiv("fish_"+i+"_"+j, topPx,lftPx,addImg(IMG_YELLOW_FISH));
       }
        if ( row[j]== BLUE_FISH ) {
            nbTotalFish++;
            /* Display the blue fish */
            addDiv("fish_"+i+"_"+j, topPx,lftPx,addImg(IMG_BLUE_FISH));
        }
        if ( row[j]== BLACK_WHITE_CAT ) {
            /* Display the black & white miaou */
            addDiv("badMiaou_"+nbBadMiaou, topPx,lftPx,addImg(IMG_BLACK_WHITE_CAT));
            gameTable[i][j]=0;
            /* Create a new miaou object */
            badMiaou[nbBadMiaou]=new miaouObject( BLACK_WHITE_CAT , 'badMiaou_'+nbBadMiaou , topPx, lftPx, j , i, W,H) ;
            nbBadMiaou++;
        }
        if ( row[j]== 10 ) {
            /* Display the score panel */
            addDiv("scoreId", topPx,lftPx,addImg(IMG_BLUE_FISH)+addImg("0")+addImg("0"));
       }
        if ( row[j]== HOME ) {
            /* Display the wall panel instead of the home */
            addDiv("homeId", topPx,lftPx,addImg(IMG_WALL));
        }
        if ( sCode.substring(0,1)== SHOE ) {
            /* Display the shoe */
            var nbShoe=sCode.substr(2);
            addDiv("shoeId_"+nbShoe, topPx,lftPx,addImg(IMG_SHOE));
            var shoeId=document.getElementById("shoeId_"+nbShoe);
            //Store shoe number
            shoeId.setAttribute("nbShoe", nbShoe);

        }
        if ( sCode.substring(0,2)==SPECIAL_WALL ) {
            /* Display the wall panel instead of the special wall */
            var nbSpecialWall=sCode.substr(3);
            addDiv("specialWallId_"+nbSpecialWall, topPx,lftPx,addImg(IMG_WALL));
            var specialWallId=document.getElementById("specialWallId_"+nbSpecialWall);
            //Store special wall's coordonnates
            specialWallId.setAttribute("xPos", j);
            specialWallId.setAttribute("yPos", i);
        }
        if ( row[j]== 99 ) {
            /* Display the debug panel */
            addDiv("debugId", topPx,lftPx,"");
        }
        lftPx+=W;
    }
    /* Ligne suivante */
    topPx+=H;
    lftPx=ORI_LFT_PX ;
}

/* Catch keyboard event and move the orange miaou */
document.onkeypress= function(e) {
    
    var e=window.event || e;
    var yPos=miaou.yPos;
    var xPos=miaou.xPos;
    if (   e.keyCode==37 && miaou.isObstacle(yPos,xPos-1) == false ) 
        /* Miaou moves left */
        miaou.moveLeft();
    if (   e.keyCode==39 && miaou.isObstacle(yPos,xPos+1) == false )
        /* Miaou moves right */
        miaou.moveRight();
    if (   e.keyCode==38 && miaou.isObstacle(yPos-1,xPos) == false )
        /* Miaou moves up */
        miaou.moveUp();
    if (   e.keyCode==40 && miaou.isObstacle(yPos+1,xPos) == false ) 
        /* Miaou moves down */
        miaou.moveDown();
        
    if ( e.keyCode==13 ) {
        /* Miaou jumps */
        miaou.jump();
    }
} 

 /* Display Miaou */
 miaou.updatePosition();
}

/**
 * Change the game's speed
 * when a fish is eaten 
 */
function changeSpeed() {
    
    var newSpeed=0;
    newSpeed = currentSpeed ; /* get the current speed by default */
    
    //Get then new speed with the eaten fish rate  
    if ( nbEatFish>0 && nbEatFish<=nbTotalFish ) {
        var eatRatio=nbEatFish/nbTotalFish ; 
        if ( eatRatio < 0.5 )                           newSpeed = SPEED_SLOW ; 
        else if ( eatRatio >= 0.5 && eatRatio < 0.75 )  newSpeed = SPEED_MIDDLE ; 
        else                                            newSpeed = SPEED_HIGH ; 
    }
    //Update the time if the new speed if different than the current speed
    if ( newSpeed != currentSpeed ) {
        /* Change the speed */
        clearInterval(timer); /* Re-initialize the current time interval */
        currentSpeed=newSpeed;
        timer=setInterval("new autoMoveObject(badMiaou).autoMoveAll()", currentSpeed ); /* Set a new time interval */ 
    }
}
/**
 * Initialize the game's speed at the beginning of a new level
 */
function initSpeed() {
        currentSpeed = SPEED_SLOW ; 
        timer=setInterval("new autoMoveObject(badMiaou).autoMoveAll()", currentSpeed ); /* Set a new time interval */ 
}

function dbug( msg ) {
    if ( DEBUG_MODE == 1 ) {
        document.getElementById("debugId").innerHTML=msg;
    }
}

/**
 * Is the object can be eat ?
 * 
 * @param int The object code
 * @return boolean True if the object can be eat
 *                 False otherwise
 */                 
function isEatable( iCode ) {
    
   var bEatable=false;
   
   if ( iCode == RED_FISH || iCode == BLUE_FISH || iCode == YELLOW_FISH ) bEatable=true;
   
   return bEatable;
}

/**
 * Is the object is My Miaou ? 
 * 
 * @param int The object code
 * @return boolean True if the object is My Miaou 
 *                 False otherwise
 */                 
function isMyMiaou( iCode ) {
 
    var bMyMiaou=false;
    if ( iCode == MY_MIAOU ) bMyMiaou=true;
    
    return bMyMiaou ;
 
}

/**
 * Is the object is lethal ?
 * 
 * @param int The object code
 * @return boolean True if the object is lethal
 *                 False otherwise
 */                 
function isLethal( iCode ) {
    
   bLethal=false;
   
   if ( iCode == BLACK_CAT || iCode == BLACK_WHITE_CAT  ) bLethal=true;
   
   return bLethal;
}

/**
 * Start a new level 
 */
function start() {
    //Clean the document
    if ( confirm("Prêt pour jouer à MIAOUUUUU ?\n\n              **** Niveau "+currentLevel+" ****")) {
        init();
        adaptScreen();
        displayGameTable() ;
        initSpeed(); /* Initialize the speed of game */
    }
 }

/*****************************************************************************
 *                       START A NEW GAME
 *****************************************************************************/
 start();   